package com.ruoyi.common.core.utils.http;

//import net.sf.json.JSONObject;

import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;

//钉钉发起请求
public class SimpleHttpClientUtil {


    private static volatile HttpClient httpClient;


    private SimpleHttpClientUtil() {
    }
    /**
     * GET 方式请求
     * 参数通过 url 拼接
     *
     * @param host      请求地址
     * @param path      接口路径
     * @param paramsMap 请求参数
     * @return
     * @throws IOException
     */
    public static HttpResponse doGet(String host, String path, Map<String, String> paramsMap) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpGet httpGet = new HttpGet(getRequestUrl(host, path, paramsMap));
        httpGet.setConfig(requestConfig);
        httpGet.setHeader(HTTP.CONTENT_TYPE, ContentType.create(ContentType.APPLICATION_FORM_URLENCODED
                .getMimeType(), Consts.UTF_8).toString());
        return httpClient.execute(httpGet);
    }


    public static HttpResponse doGet(String host, String path, Map<String, String> paramsMap, LinkedHashMap<String, String> headers) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpGet httpGet = new HttpGet(getRequestUrl(host, path, paramsMap));
        httpGet.setConfig(requestConfig);
        httpGet.setHeader(HTTP.CONTENT_TYPE, ContentType.create(ContentType.APPLICATION_FORM_URLENCODED
                .getMimeType(), Consts.UTF_8).toString());
        if (null != headers) {
            for (String key : headers.keySet()) {
                httpGet.setHeader(key, headers.get(key));
            }
        }
        return httpClient.execute(httpGet);
    }

    /**
     * GET 方式请求
     * 参数通过 url 拼接
     *
     * @param host      请求地址
     * @param path      接口路径
     * @param paramsMap 请求参数
     * @return
     * @throws IOException
     */
    public static HttpResponse doGet(String host, String path, Map<String, String> paramsMap, String tokenParam, String tokenValue) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpGet httpGet = new HttpGet(getRequestUrl(host, path, paramsMap));
        httpGet.setConfig(requestConfig);
        httpGet.setHeader(HTTP.CONTENT_TYPE, ContentType.create(ContentType.APPLICATION_FORM_URLENCODED
                .getMimeType(), Consts.UTF_8).toString());
        if (StringUtils.hasLength(tokenParam)) {
            httpGet.setHeader(tokenParam, tokenValue);
        }

        return httpClient.execute(httpGet);
    }

    public static HttpResponse doDelete(String host, String path, Map<String, String> paramsMap, String tokenParam, String tokenValue) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpDelete httpGet = new HttpDelete(getRequestUrl(host, path, paramsMap));
        httpGet.setConfig(requestConfig);
        httpGet.setHeader(HTTP.CONTENT_TYPE, ContentType.create(ContentType.APPLICATION_FORM_URLENCODED
                .getMimeType(), Consts.UTF_8).toString());
        if (StringUtils.hasLength(tokenParam)) {
            httpGet.setHeader(tokenParam, tokenValue);
        }

        return httpClient.execute(httpGet);
    }

    /**
     * POST 方式请求
     * 参数通过 url 拼接
     *
     * @param host      请求地址
     * @param path      接口路径
     * @param paramsMap 请求参数
     * @return
     * @throws IOException
     */
    public static HttpResponse doPost(String host, String path, Map<String, String> paramsMap) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpPost httpPost = new HttpPost(getRequestUrl(host, path, paramsMap));
        httpPost.setConfig(requestConfig);
        httpPost.setHeader(HTTP.CONTENT_TYPE, ContentType.create(ContentType.APPLICATION_FORM_URLENCODED
                .getMimeType(), Consts.UTF_8).toString());

        return httpClient.execute(httpPost);
    }

    /**
     * POST 方式请求
     * 参数通过 Body 传送,JSON 格式
     *
     * @param host       请求地址
     * @param path       接口路径
     * @param jsonParams 请求参数(json 字符串)
     * @return
     */
    public static HttpResponse doPost(String host, String path, String jsonParams) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpPost httpPost = new HttpPost(host + path);
        StringEntity stringentity = new StringEntity(jsonParams, ContentType.APPLICATION_JSON);
        httpPost.setEntity(stringentity);
        httpPost.setConfig(requestConfig);
        httpPost.addHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
        return httpClient.execute(httpPost);
    }

    /**
     * POST 方式请求
     * 参数通过 Body 传送,JSON 格式
     *
     * @param host       请求地址
     * @param path       接口路径
     * @param jsonParams 请求参数(json 字符串)
     * @return
     */
    public static HttpResponse doPost(String host, String path, String jsonParams, String tokenParam, String tokenValue) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpPost httpPost = new HttpPost(host + path);
        if (StringUtils.hasLength(jsonParams)) {
            StringEntity stringentity = new StringEntity(jsonParams, ContentType.APPLICATION_JSON);
            httpPost.setEntity(stringentity);
        }
        httpPost.setConfig(requestConfig);
        httpPost.addHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
        if (StringUtils.hasLength(tokenParam)) {
            httpPost.setHeader(tokenParam, tokenValue);
        }
        return httpClient.execute(httpPost);
    }



    public static HttpResponse doPost(String host, String path, String jsonParams, LinkedHashMap<String, String> headers) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpPost httpPost = new HttpPost(host + path);
        if (StringUtils.hasLength(jsonParams)) {
            StringEntity stringentity = new StringEntity(jsonParams, ContentType.APPLICATION_JSON);
            httpPost.setEntity(stringentity);
        }
        httpPost.setConfig(requestConfig);
        httpPost.addHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
        if (null != headers) {
            for (String key : headers.keySet()) {
                httpPost.setHeader(key, headers.get(key));
            }
        }
        return httpClient.execute(httpPost);
    }

    /**
     * POST 方式请求
     * 文件上传
     *
     * @param host             请求地址
     * @param path             接口路径
     * @param paramsMap        请求参数
     * @param fileInputStream  待上传文件流
     * @param name             文件对应字段名
     * @param fileOriginalName 原始文件名
     * @return
     */
    public static HttpResponse doPost(String host, String path, Map<String, String> paramsMap,
                                      InputStream fileInputStream, String name, String fileOriginalName) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpPost httpPost = new HttpPost(host + path);
        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
        // 解决中文文件名乱码问题
        entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        entityBuilder.setCharset(Consts.UTF_8);
        ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), Consts.UTF_8);
        if (paramsMap != null) {
            for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
                entityBuilder.addTextBody(entry.getKey(), entry.getValue(), contentType);
            }
        }
        if (fileInputStream != null && name != null && fileOriginalName != null) {
            entityBuilder.addBinaryBody(name, fileInputStream, ContentType.DEFAULT_BINARY, fileOriginalName);
        }
        httpPost.setEntity(entityBuilder.build());
        httpPost.setConfig(requestConfig);

        return httpClient.execute(httpPost);
    }


    /**
     * 初始化 httpClient
     *
     * @return
     */
    private static HttpClient initHttpClient() {
        if (httpClient == null) {
            synchronized (SimpleHttpClientUtil.class) {
                if (httpClient == null) {
                    httpClient = HttpClients.createDefault();
                }
            }
        }
        return httpClient;
    }

    /**
     * 获取完整请求地址(包含参数)
     * 参数拼接在 url 中
     *
     * @param host      请求地址
     * @param path      接口路径
     * @param paramsMap 请求参数
     * @return
     */
    public static String getRequestUrl(String host, String path, Map<String, String> paramsMap) {
        StringBuilder reqUrl = new StringBuilder(host).append(path);
        if (paramsMap != null && !paramsMap.isEmpty()) {
            StringBuilder params = new StringBuilder();
            for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
                params.append("&" + entry.getKey() + "=" + entry.getValue());
            }
            String paramConnector = "?";
            if (!host.contains(paramConnector) && !path.contains(paramConnector)) {
                reqUrl.append(paramConnector);
                reqUrl.append(params.toString().substring(1));
            } else {
                reqUrl.append(params.toString());
            }
        }

        return reqUrl.toString();
    }







    /*

    //天印服务器接口信息
    public static String sendPOST(String apiUrl, JSONObject data, LinkedHashMap<String, String> headers, String encoding) throws Exception {

        //System.out.println(myData);
        byte[] stream = data.toString().getBytes(encoding);
        // 设置HTTP请求头
        HttpEntityEnclosingRequestBase req = new HttpPost(apiUrl);

        // project-id为用户的projectId
        //req.addHeader("X-timevale-project-id", ProjectID);
        // signature为之前生成的签名
        //req.addHeader("X-timevale-signature", signature);
        if (null != headers) {
            for (String key : headers.keySet()) {
                req.addHeader(key, headers.get(key));
            }
        }

        // 签名模式：1、sort-parameters——对参数名称按ASCII码排序后签名，2、package——对整个httpbody签名。默认为package模式
        req.addHeader("X-timevale-mode", "package");
        // 签名算法：1、HMAC-SHA256，2、RSA。默认为HMAC-SHA256
        req.addHeader("X-timevale-signature-algorithm", "HMAC-SHA256");

        // 设置HTTP请求体
        HttpEntity entity = new ByteArrayEntity(stream, ContentType
                .create(ContentType.APPLICATION_JSON.getMimeType(), Consts.UTF_8));
        req.setEntity(entity);

        // 执行请求
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        CloseableHttpClient cli = httpClientBuilder.build();
        HttpResponse res = cli.execute(req);
        int statusCode = res.getStatusLine().getStatusCode();
        System.out.println(statusCode);
        if(200 != statusCode){
            System.out.println(statusCode);
        }
        // 获取响应
        InputStream in = res.getEntity().getContent();

        byte[] resp = readStream(in);
        String strRes = new String(resp,Consts.UTF_8);
        //System.out.println(strRes);
        cli.close();
        return strRes;
    }



    public static byte[] readStream(InputStream in) throws IOException {

        ByteArrayOutputStream output = new ByteArrayOutputStream();

        byte[] buffer = new byte[1024 * 10];
        try {

            int n = 0;
            while ((n = in.read(buffer)) != -1) {
                output.write(buffer, 0, n);
            }

            return output.toByteArray();

        } finally {
            in.close();
            output.close();
        }
    }

    */



}
